﻿#include "Earth3DView.h"
#include <amk3/EarthWrapper.h>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QThread>
#include <QString>
#include <QMessageBox>
#include <amk3/ScreenDisplay.h>
#include <amk3/OsgGraphicView.h>
#include <amk3/Apps/OsgCapture.h>
#include <QFileDialog>
#include <osgDB/WriteFile>
#include "InsConfig.h"

//#include <5.4.2/QtQuick/private/qquickwindow_p.h>

//class UpdateThread : public QThread
//{
//    // QThread interface
//protected:
//    void run(){
//        EarthWrapper::intance()->createMapNode();
//    }
//};

Earth3DView::Earth3DView()
{
    _stereo = false;
}

void Earth3DView::init()
{
    OsgGraphicView::init();
    EarthWrapperOptions options;
    options.viewer = _viewer;
    EarthWrapper::instance()->init(options);
    //emit this->singlInted();

	//MainService::instance()->setMidNightStyle(true);

	osg::Camera* camera = _viewer->getCamera();

	float fov = 60;
	if (InsConfig::instance()->camera_fov > 0)
	{
		fov = InsConfig::instance()->camera_fov;
	}
	float vw = this->width();
	float vh = this->height();
	float vh2 = InsConfig::instance()->camera_viewheight;
	float vw2 = InsConfig::instance()->camera_viewwidth;
	if (vh2 > 0 && vw2 > 0)
	{
		vh = vh2;
		vw = vw2;
		
	}
	float asp = vw / vh;
	camera->setProjectionMatrixAsPerspective(fov, asp, 1, 10000000);
	camera->setComputeNearFarMode(osg::Camera::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
	camera->setViewport(0, 0, vw, vh);
	this->SetGraphicsViewport(vw2, vh2);
	this->SetFovNearFar(fov, -1, -1);
	//_viewer->getCamera()->setComputeNearFarMode(osg::Camera::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);

    ScreenDisplay::instance()->setEnabled(false);
}

void Earth3DView::render()
{
	EarthWrapper::instance()->render();
}

#include <amk3/TransUtil.h>
void Earth3DView::getCameraPosition()
{
	osgViewer::Viewer* viewer = EarthWrapper::instance()->getViewer();
	if (!viewer) return;

	//osg::Vec3 vPosEye, vCenter, vUp;
	//viewer->getCamera()->getViewMatrixAsLookAt(vPosEye, vCenter, vUp);//获取视点信息
	//osg::Matrix mat = viewer->getCamera()->getInverseViewMatrix();
	//osg::Vec3d scale = osg::Vec3d();
	//osg::Quat so;
	//osg::Vec3d translate = osg::Vec3d();
	////经过缩放后的模型最好使用decompose矩阵分解，不然getRotate所得旋转量可能不正确
	//osg::Quat rotation;
	//mat.decompose(translate, rotation, scale, so);
	//osg::Vec3 hpr = TransUtil::matrix4_2_HPR_2(mat);

	osg::Vec3 hpr,pos;
	osg::Matrix mat = viewer->getCamera()->getViewMatrix();

	TransUtil::viewMatrix2CameraPose_Cesium(mat,pos,hpr);
	double h = osg::RadiansToDegrees(hpr[0]);
	double p = osg::RadiansToDegrees(hpr[1]);
	double r = osg::RadiansToDegrees(hpr[2]);

	QString msg = QString("CAMPOS: %1 %2 %3; H:%4 P:%5 R:%6")
		.arg(QString::number(pos[0], 'f', 3))
		.arg(QString::number(pos[1], 'f', 3))
		.arg(QString::number(pos[2], 'f', 3))
		.arg(QString::number(h, 'f', 3))
		.arg(QString::number(p, 'f', 3))
		.arg(QString::number(r, 'f', 3));
	emit this->signalShowMessage(msg);

		//.arg(translate[0], translate[1], translate[2],h,p,r);
}

void Earth3DView::setCameraPose(osg::Vec3 pos, osg::Vec3 hpr)
{
	osgViewer::Viewer* viewer = EarthWrapper::instance()->getViewer();
	if (!viewer) return;

	osg::Matrix cam_pose = TransUtil::cemeraPose2ViewMatrix_Cesium(pos, hpr);
	viewer->setCameraManipulator(0);
	viewer->getCamera()->setViewMatrix(cam_pose);

	////构造视图矩阵，视图矩阵：把世界坐标转换为相机坐标，也就是把一个点从世界坐标系转换到相机坐标系
	////首先把坐标系原点移动相机位置：osg::Matrix::translate(-pos)
	////然后根据相机相对于世界的旋转角度和顺序，让世界按照相同的顺序和负角度进行旋转。
	//osg::Matrix cam_pose;
	//cam_pose.postMult(osg::Matrix::translate(-pos));
	//cam_pose.postMult(osg::Matrix::rotate(osg::DegreesToRadians(-90.0), 1, 0, 0));
	//cam_pose.postMult(osg::Matrix::rotate(osg::DegreesToRadians(-hpr[0]), 0, 1, 0));
	//cam_pose.postMult(osg::Matrix::rotate(osg::DegreesToRadians(-hpr[1]), 1, 0, 0));
	//cam_pose.postMult(osg::Matrix::rotate(osg::DegreesToRadians(-hpr[2]), 0, 0, 1));
	//viewer->setCameraManipulator(0);
	//viewer->getCamera()->setViewMatrix(cam_pose);
	//return;


	////构造反视图矩阵，反视图矩阵：把相机坐标转换为世界坐标，也就是把一个点从相机坐标系转换到世界坐标系
	////然后根据相机相对于世界的旋转顺序，按照相反的顺序进行旋转。
	////然后把点坐标平移(相机相对于世界的坐标)
	//cam_pose.preMult(osg::Matrix::rotate(osg::DegreesToRadians(90.0), 1, 0, 0));
	//cam_pose.preMult(osg::Matrix::rotate(osg::DegreesToRadians(hpr[0]), 0, 1, 0));
	//cam_pose.preMult(osg::Matrix::rotate(osg::DegreesToRadians(hpr[1]), 1, 0, 0));
	//cam_pose.preMult(osg::Matrix::rotate(osg::DegreesToRadians(hpr[2]), 0, 0, 1));
	//cam_pose.postMult(osg::Matrix::translate(pos));

	//osg::Matrix cam_pose_r;
	//cam_pose_r = osg::Matrix::inverse(cam_pose);

	

	//osg::Matrix mat = viewer->getCamera()->getInverseViewMatrix();

}

#include <QQmlContext>
void Earth3DView::registerQMLProperty(const QString &name, const QVariant& value)
{
    rootContext()->setContextProperty(name, value);
}


void Earth3DView::slotStereo()
{
    this->_stereo = !_stereo;
}

void Earth3DView::slotGotoHenan()
{
    osgEarth::Viewpoint vp( "Henan",113,33.6,0, 0, -70, 6e5 );
    EarthWrapper::instance()->getManipulator()->setViewpoint(vp,3.0);
}

void Earth3DView::slotGotoHome()
{
    osgEarth::Viewpoint vp( "Home",113,33.6,0, 0, -90, 10e6 );
    EarthWrapper::instance()->getManipulator()->setViewpoint(vp,3.0);
}

void Earth3DView::slotSceneInited()
{
    //emit this->signalCityRanking();
    //osgEarth::Viewpoint vp( "Henan",113,33.6,0, 0, -70, 6e5 );
    //EarthWrapper::intance()->getManipulator()->setViewpoint(vp,5.0);
}

void Earth3DView::mousePressEvent(QMouseEvent *event)
{
    OsgGraphicView::mousePressEvent(event);
    //emit this->signalCloseAnnoInfo();
    //if(event->isAccepted()) return;
    //this->rootObject()->setFocus(true);
    //emit closeChildMenu();
	
}

void Earth3DView::mouseReleaseEvent(QMouseEvent *event)
{
    OsgGraphicView::mouseReleaseEvent(event);
	this->getCameraPosition();
}

void Earth3DView::mouseDoubleClickEvent(QMouseEvent *event)
{
    OsgGraphicView::mouseDoubleClickEvent(event);
}

void Earth3DView::mouseMoveEvent(QMouseEvent *event)
{
    OsgGraphicView::mouseMoveEvent(event);
	
}


void Earth3DView::keyPressEvent(QKeyEvent *e)
{
	switch (e->key()) {
	case Qt::Key_0:
	{
		osgEarth::Viewpoint vp = EarthWrapper::instance()->getManipulator()->getViewpoint();
		std::string str = vp.getConfig().toJSON(true);
		QMessageBox::information(0, "", QString::fromStdString(str));
		break;
	}
	case Qt::Key_C:
	{


		break;
	}

}
return QQuickView::keyPressEvent(e);
}


void Earth3DView::resizeEvent(QResizeEvent * event)
{
	OsgGraphicView::resizeEvent(event);
	
	float vh2 = InsConfig::instance()->camera_viewheight;
	float vw2 = InsConfig::instance()->camera_viewwidth;
	if (vh2 > 0 && vw2 > 0)
	{
		this->SetGraphicsViewport(vw2, vh2);
	}
}

